package objects;

import java.awt.Graphics2D;
import map.Map;
import map.Tile;
import engine.Game;

/**
 * The class that represents Creatures.
 * 
 * @author Kyle_Solo
 */
public class Creature extends GameObject {

	/**
	 * @author Kyle_Solo
	 */
	protected enum DIRECTION {
		E, N, NE, NW, S, SE, SW, W
	}

	/**
	 * This variable lets player-controlled creatures move left/right by alternating diagonal
	 * movement. It tracks whether it should attempt to go up or down with the next move, though it
	 * will go to whichever space is open if one of the two spaces is closed.
	 */
	private boolean lastUp = false;

	/**
	 * This method makes sure it is possible to move onto the specified tile. It should take into
	 * account attributes about the creature (for example, a flying creature could fly over lava or
	 * a pit, a swimming creature into deep water...)
	 * 
	 * @param t
	 *            the tile in question
	 * @return whether or not this Creature could legally move onto Tile t
	 */
	public boolean isLegalMove(Tile t) {
		if (t == null) {
			return false;
		} else {
			if (t.getObjects() == null || t.getObjects().size() == 0) {
				return true;
			} else {
				return false;
			}
		}
	}

	/**
	 * This method moves a creature in a direction.
	 * 
	 * @param direction
	 *            one of the directions defined by Map.DIRECTION
	 * @return true if a move was made, false if no action was taken
	 */
	public boolean move(Map.DIRECTION direction) {
		Tile destination = null;
		switch (direction) {
		case N:
			destination = currentTile.getTile(0, -1, 1);
			break;
		case NE:
			destination = currentTile.getTile(1, -1, 0);
			break;
		case E: {
			// alternating movement for left/right
			Tile t1 = currentTile.getTile(1, -1, 0);
			if (!lastUp && isLegalMove(t1)) {
				destination = t1;
				lastUp = true;
			} else {
				destination = currentTile.getTile(1, 0, -1);
				lastUp = false;
			}
			break;
		}
		case SE:
			destination = currentTile.getTile(1, 0, -1);
			break;
		case S:
			destination = currentTile.getTile(0, 1, -1);
			break;
		case SW:
			destination = currentTile.getTile(-1, 1, 0);
			break;
		case W: {
			// alternating movement for left/right
			Tile t1 = currentTile.getTile(-1, 0, 1);
			if (!lastUp && isLegalMove(t1)) {
				destination = t1;
				lastUp = true;
			} else {
				destination = currentTile.getTile(-1, 1, 0);
				lastUp = false;
			}
			break;
		}
		case NW:
			destination = currentTile.getTile(-1, 0, 1);
			break;
		}

		return move(destination);
	}

	private boolean move(Tile destination) {
		assert destination != currentTile : "Trying to move to the same tile!";
		if (isLegalMove(destination)) {
			currentTile.moveObject(destination, this);
			return true;
		}
		return false;
	}

	@Override
	public boolean onTurn(Game game) {
		boolean done = false;
		if (isPlayerComtrolled()) {
			// call the function that lets the player control a Creature's actions
			done = game.playerTurn(this);
		} else {
			done = AI();
		}
		return done;
	}

	@Override
	public void render(Graphics2D g2d) {
		g2d.drawString("@", 0, 12);
	}
}
